#ifndef _DATA_TYPE_H_
#define _DATA_TYPE_H_

#include <string>
#include "livox_data_type.h"
#include "modules/common_msgs/sensor_msgs/pointcloud.pb.h"

namespace apollo {
namespace drivers {
namespace livox {

typedef apollo::drivers::PointCloud Cloud;
typedef apollo::drivers::PointXYZIT PointI;

enum LivoxLidarPos : uint8_t { FRONT, LEFT, RIGHT, REAR, EMPTY };

class LidarPacket {
 public:
  LidarPacket() {
    stamp = 0;
    livoxPos = LivoxLidarPos::EMPTY;
  }
  uint64_t stamp;
  LivoxPacket livoxPacket;
  LivoxLidarPos livoxPos;
  std::string frame_id;
  void CopyFrom(const LidarPacket src) {
    stamp = src.stamp;
    memcpy(&livoxPacket, &(src.livoxPacket), sizeof(LivoxPacket));
    livoxPos = src.livoxPos;
    frame_id = src.frame_id;
  }
};

class LidarFrame {
 public:
  LidarFrame() {
    frontCloud = std::make_shared<Cloud>();
    leftCloud = std::make_shared<Cloud>();
    rightCloud = std::make_shared<Cloud>();
    rearCloud = std::make_shared<Cloud>();
  };
  std::shared_ptr<Cloud> frontCloud;
  std::shared_ptr<Cloud> leftCloud;
  std::shared_ptr<Cloud> rightCloud;
  std::shared_ptr<Cloud> rearCloud;

  // 2. addition infos
  uint64_t startStamp;
  uint64_t endStamp;
  int seq;

  // 3. methods
  void Clear() {
    frontCloud->Clear();
    leftCloud->Clear();
    rightCloud->Clear();
    rearCloud->Clear();
  }
  void CopyFrom(const LidarFrame frame) {
    frontCloud->CopyFrom(*frame.frontCloud);
    leftCloud->CopyFrom(*frame.leftCloud);
    rightCloud->CopyFrom(*frame.rightCloud);
    rearCloud->CopyFrom(*frame.rearCloud);
    startStamp = frame.startStamp;
    endStamp = frame.endStamp;
    seq = frame.seq;
  }
};

class MixLidarFrame {
 public:
  MixLidarFrame() {
    frontCloud = std::make_shared<Cloud>();
    leftCloud = std::make_shared<Cloud>();
    rightCloud = std::make_shared<Cloud>();
    rearCloud = std::make_shared<Cloud>();
  }

  std::shared_ptr<Cloud> frontCloud;
  std::shared_ptr<Cloud> leftCloud;
  std::shared_ptr<Cloud> rightCloud;
  std::shared_ptr<Cloud> rearCloud;

  // 4. addition infos
  uint64_t startStamp{0};
  uint64_t endStamp{0};
  uint32_t seq{0};

  // 5. methods
  void Clear() {
    frontCloud->Clear();
    leftCloud->Clear();
    rightCloud->Clear();
    rearCloud->Clear();
  }
  void CopyFrom(const MixLidarFrame frame) {
    frontCloud->CopyFrom(*frame.frontCloud);
    leftCloud->CopyFrom(*frame.leftCloud);
    rightCloud->CopyFrom(*frame.rightCloud);
    rearCloud->CopyFrom(*frame.rearCloud);

    startStamp = frame.startStamp;
    endStamp = frame.endStamp;
    seq = frame.seq;
  }
  void CopyFrom(const LidarFrame frame) {
    frontCloud->CopyFrom(*frame.frontCloud);
    leftCloud->CopyFrom(*frame.leftCloud);
    rightCloud->CopyFrom(*frame.rightCloud);
    rearCloud->CopyFrom(*frame.rearCloud);

    startStamp = frame.startStamp;
    endStamp = frame.endStamp;
    seq = frame.seq;
  }
};

}  // namespace livox
}  // namespace drivers
}  // namespace apollo

#endif
